// import { DownloadOutlined, EyeOutlined } from '@ant-design/icons';
import { useEffect, useMemo, useState } from 'react';

import { useControllableValue } from 'ahooks';
import {
  Upload as AntdUpload,
  type UploadProps as AntdUploadProps,
  type UploadFile,
  message
} from 'antd';
import { LIST_IGNORE } from 'antd/es/upload/Upload';

import { store } from '@/store';

// import { loadingStore } from '@/store/loading';
import { filePlusPage, filePlusUpload } from '@/services/base/kuozhangongnengwenjianguanliPlus';
import { formatFileSize, openUrl, parseSrc } from '@/utils';
import { Icon } from '@iconify/react';

import styles from './index.module.scss';

// 文件分隔符
const SEPARATOR = '?';

/** 上传接口返回值类型 */
export type FileResponse = BASE.FileInfo;

export type UploadProps<T extends FileResponse = FileResponse> = Omit<
  AntdUploadProps<T>,
  'onChange' | 'children'
> & {
  value?: string;
  onChange?: (value?: string) => void;
  children?: React.ReactNode | ((file?: UploadFile<T>) => React.ReactNode);
  base64?: boolean; // 新增属性，用于指示是否生成base64字符串
  onBase64Change?: (base64: string) => void; // 新增属性，用于处理base64字符串结果
  publicRead?: boolean;
  maxSize?: number;
};

const Upload = <T extends FileResponse = FileResponse>({
  children,
  beforeUpload: beforeUploadProps,
  base64: base64Props,
  onBase64Change: onBase64ChangeProps,
  publicRead,
  maxSize: maxFileSizeProps,
  ...rest
}: UploadProps<T>) => {
  const [value, setValue] = useControllableValue<UploadProps<T>['value']>(rest);
  const [fileListDict, setFileListDict] = useState<Record<string, UploadFile<T>>>({});

  // 自定义上传
  const customRequest: AntdUploadProps<T>['customRequest'] = async (options) => {
    const file = options.file as File;

    const formData = new FormData();
    formData.append('file', file);
    formData.append('name', file.name);
    formData.append('filePurpose', '1');
    formData.append('showState', '1');
    if (publicRead) {
      formData.append('publicRead', 'true');
    }
    try {
      const res = await filePlusUpload(
        {} as ArgumentsType<typeof filePlusUpload>[0],
        {},
        {} as ArgumentsType<typeof filePlusUpload>[2],
        {
          headers: {
            'Content-Type': 'multipart/form-data'
          },
          data: formData,
          timeout: 60 * 10000,
          skipErrorHandler: true
        }
      );

      if (!res.data) {
        throw new Error('上传失败');
      }

      options.onSuccess?.(res.data as T);
    } catch (e) {
      options.onError?.(e as Error);
      store.app?.message.error(typeof e === 'string' ? e : `${file.name}上传失败！`);
    }
  };
  const fileList = useMemo(() => {
    const res: UploadFile<T>[] = [];
    if (value) {
      for (const url of value.split(SEPARATOR)) {
        if (fileListDict[url]) {
          res.push(fileListDict[url]);
        } else {
          res.push({
            uid: url,
            name: url,
            status: 'done',
            url: parseSrc(url),
            response: {
              url: url
            } as T
          });
        }
      }
    }

    return res;
  }, [fileListDict, value]);

  // 上传前操作
  const beforeUpload: AntdUploadProps<T>['beforeUpload'] = async (file, fileList1) => {
    // const suffix = file.name.split('.').pop();
    // 大小处理
    if (maxFileSizeProps && file.size > maxFileSizeProps) {
      message.error(`上传文件大小不能超过: ${formatFileSize(maxFileSizeProps)}`);

      return LIST_IGNORE;
    }
    // 数量限制
    if (rest?.maxCount && rest.maxCount > 1 && rest.maxCount <= fileList.length) {
      message.error(`上传数量不能超过${rest.maxCount}个`);

      return LIST_IGNORE;
    }
    if (rest.accept) {
      // if (onlyImgProps) {
      //   if (!imgFileType.includes(suffix!)) {
      //     message.info(`只能上传${imgFileType.join('/')}格式的文件`);

      //     return LIST_IGNORE;
      //   }
      // }
      // 是否可接受文件类型
      const acceptTypes = rest.accept.split(',').map((type) => type.trim().toLowerCase());
      const fileName = file.name.toLowerCase();
      const isAccepted = acceptTypes.some((type) => {
        if (type.startsWith('.')) {
          return fileName.endsWith(type);
        }
        // 也可以支持 image/* 这种写法
        if (type.endsWith('/*')) {
          return file.type.startsWith(type.replace('/*', ''));
        }
        return file.type === type;
      });
      if (!isAccepted) {
        message.error(`上传的文件类型不支持，仅支持: ${acceptTypes.join(', ')}`);
        return AntdUpload.LIST_IGNORE;
      }
    }

    if (base64Props) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => {
          // 调用onChange或onBase64Change，传递base64字符串
          const base64String = reader.result as string;

          if (onBase64ChangeProps) {
            onBase64ChangeProps(base64String);
          } else {
            setValue(base64String);
          }
          resolve(AntdUpload.LIST_IGNORE); // 阻止文件上传
        };

        reader.onerror = (error) => {
          // message.error(`文件读取错误: ${error}`);
          reject(error);
        };
      });
    }

    return beforeUploadProps?.(file, fileList1);
  };

  const getFileList = async (url: string) => {
    const res = await filePlusPage({
      url: url
    });
    return res.data;
  };

  useEffect(() => {
    if (value) {
      for (const url of value.split(SEPARATOR)) {
        if (fileListDict[url]) {
          continue;
        }
        getFileList(url).then((res) => {
          const data = res?.records?.[0];
          if (data) {
            setFileListDict((prev: any) => {
              return {
                ...prev,
                [url]: {
                  uid: url,
                  name: data?.originalFilename || url,
                  status: 'done',
                  url: parseSrc(url),
                  response: data
                }
              };
            });
          }
        });
      }
    }
  }, [value]);

  const onChange: AntdUploadProps<T>['onChange'] = (info) => {
    setFileListDict((prev) => {
      return {
        ...prev,
        [info.file.uid]: info.file
      };
    });

    const list = info.fileList.map((v) => v.response?.url || v.uid).join(SEPARATOR);
    setValue(list);
  };

  const remove = (file: UploadFile<T>, e: React.MouseEvent) => {
    e.stopPropagation();

    if (file) {
      const list = fileList.filter((v) => v.uid !== file.uid);
      const listStr = list.map((v) => v.response?.url || v.uid).join(SEPARATOR);
      setValue(listStr);
    }
  };
  const downFile = async (file: any) => {
    // 显示全局 loading 提示，返回关闭函数
    try {
      const response = await fetch(file.url);
      const blob = await response.blob();
      const downloadUrl = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = downloadUrl;
      a.download = file.customName || file.name; // 👈 使用自定义文件名
      document.body.appendChild(a);
      a.click();
      a.remove();
      window.URL.revokeObjectURL(downloadUrl);
    } catch (error) {
      message.error('下载失败');
    }
  };
  const previewFile = (file: any) => {
    openUrl(file?.uid);
  };

  return (
    <AntdUpload<T>
      onPreview={previewFile}
      onDownload={downFile}
      showUploadList={{
        showDownloadIcon: true, // 显示下载图标
        showPreviewIcon: true // 显示预览图标
        // downloadIcon: <DownloadOutlined />,  // 自定义下载图标
        // previewIcon: <EyeOutlined />,       // 自定义预览图标
      }}
      {...rest}
      capture={true} // 允许从设备选择文件夹
      beforeUpload={beforeUpload}
      customRequest={customRequest}
      fileList={fileList}
      onChange={onChange}
    >
      {typeof children === 'function' ? (
        <div className={styles['upload-wrapper']}>
          {fileList[fileList.length - 1] && (
            <div
              className={styles['remove']}
              onClick={remove.bind(null, fileList[fileList.length - 1])}
            >
              <Icon icon="ri:close-fill" />
            </div>
          )}
          {children(fileList[fileList.length - 1])}
        </div>
      ) : (
        children
      )}
    </AntdUpload>
  );
};

export default Upload;
